home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / INTERP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.1 KB  |  262 lines

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <GL/glut.h>
  7. #include "texture.h"
  8.  
  9. static char defaultFile[] = "data/mandrill256.rgb";
  10. GLuint *img, *black, *avgLum, *lum;
  11. GLsizei w, h;
  12. GLint comp;
  13. GLboolean isIR;
  14.  
  15. #define RW 0.3086
  16. #define GW 0.6094
  17. #define BW 0.0820
  18.  
  19. GLuint *in0, *in1;
  20. GLfloat x = 1.;
  21.  
  22. #define BRIGHTNESS    0
  23. #define CONTRAST    1
  24. #define SATURATION    2
  25. int nOperations = 3;
  26. int operation = 0;
  27.  
  28.  
  29. void set_img_pointers(void)
  30. {
  31.     switch(operation) {
  32.     case CONTRAST:
  33.     in0 = avgLum;
  34.     printf("modifying contrast\n");
  35.     break;
  36.     case SATURATION:
  37.     in0 = lum;
  38.     printf("modifying saturation\n");
  39.     break;
  40.     case BRIGHTNESS:
  41.     in0 = black;
  42.     printf("modifying brightness\n");
  43.     break;
  44.     default:
  45.     assert(0);
  46.     }
  47. }
  48.  
  49. void init(void)
  50. {
  51.     const char *renderer;
  52.  
  53.     set_img_pointers();
  54.  
  55.     renderer = (char*) glGetString(GL_RENDERER);
  56.     isIR = (renderer[0] == 'I' && renderer[1] == 'R');
  57. }
  58.  
  59. GLuint *alloc_image(void)
  60. {
  61.     GLuint *ptr;
  62.  
  63.     ptr = (GLuint *)malloc(w * h * sizeof(GLuint));
  64.     if (!ptr) {
  65.     fprintf(stderr, "malloc of %d bytes failed.\n", w * h * sizeof(GLuint));
  66.     }
  67.     return ptr;
  68. }
  69.  
  70. void load_img(const char *fname)
  71. {
  72.     int i;
  73.     GLubyte *src, *dst;
  74.     GLfloat pix, avg;
  75.  
  76.     img = read_texture(fname, &w, &h, &comp);
  77.     if (!img) {
  78.     fprintf(stderr, "Could not open %s\n", fname);
  79.     exit(1);
  80.     }
  81.  
  82.     black = alloc_image();
  83.     memset(black, 0, w * h * sizeof(GLuint));
  84.  
  85.     lum = alloc_image();
  86.     src = (GLubyte *)img;
  87.     dst = (GLubyte *)lum;
  88.     avg = 0.;
  89.     /* compute average luminance at same time that we set luminance image.
  90.      * note that little care is taken to avoid mathematical error when
  91.      * computing overall average... */
  92.     for (i = 0; i < w * h; i++) {
  93.     pix = (float)src[0]*RW + (float)src[1]*GW + (float)src[2]*BW;
  94.     if (pix > 255) pix = 255;
  95.     dst[0] = dst[1] = dst[2] = pix;
  96.     avg += pix / 255.;
  97.     src += 4;
  98.     dst += 4;
  99.     }
  100.  
  101.     avgLum = alloc_image();
  102.     pix = avg * 255. / (float)(w*h);
  103.     dst = (GLubyte *)avgLum;
  104.     for (i = 0; i < w * h; i++) {
  105.     dst[0] = dst[1] = dst[2] = pix;
  106.     dst += 4;
  107.     }
  108. }
  109.  
  110. void reshape(GLsizei winW, GLsizei winH) 
  111. {
  112.     glViewport(0, 0, w, h);
  113.     glLoadIdentity();
  114.     glOrtho(0, winW, 0, winH, 0, 5);
  115. }
  116.  
  117. void draw(void)
  118. {
  119.     GLenum err;
  120.     GLfloat s, absx, abs1minusx;
  121.  
  122.     glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT);
  123.     glRasterPos2i(0, 0);
  124.     glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in0);
  125.  
  126.     absx = fabs(x);
  127.     abs1minusx = fabs(1.-x);
  128.     s = absx > abs1minusx ? absx : abs1minusx;
  129.  
  130.     if (!isIR) {
  131.     glAccum(GL_ACCUM, (1. - x) / s);
  132.     glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1);
  133.     glAccum(GL_ACCUM, x/s);
  134.     glAccum(GL_RETURN, s);
  135.     } else {
  136.     if (fabs(x) < 1. && fabs(1. - x) < 1) {
  137.         glAccum(GL_ACCUM, 1. - x);
  138.         glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1);
  139.         glAccum(GL_ACCUM, x);
  140.         glAccum(GL_RETURN, 1);    
  141.     } else {
  142.         absx = fabs(x);
  143.         abs1minusx = fabs(1.-x);
  144.         s = absx > abs1minusx ? absx : abs1minusx;
  145.  
  146.         glAccum(GL_ACCUM, .8 * ((1. - x) / s));
  147.         glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1);
  148.         glAccum(GL_ACCUM, .8 * x/s);
  149.         glAccum(GL_RETURN, 1.2 * s);
  150.     }
  151.     }
  152.  
  153.     err = glGetError();
  154.     if (err != GL_NO_ERROR) printf("Error:  %s\n", gluErrorString(err));
  155.  
  156.     glutSwapBuffers();
  157. }
  158.  
  159. /* ARGSUSED1 */
  160. void key(unsigned char key, int xpos, int ypos)
  161. {
  162.     if (key == 27) exit(0);
  163.  
  164.     operation = (operation + 1) % nOperations;
  165.     set_img_pointers();
  166.     draw();
  167. }
  168.  
  169. int mouseOriginX;
  170. int moveCalled = 0;
  171. float deltaSinceDraw = 0.;
  172.  
  173. void idle(void);
  174.  
  175. void clamp_x(void)
  176. {
  177.     if (x > 3.99 && isIR) x = 3.99;
  178.     else if (x < -4. && isIR) x = -4.;
  179. }
  180.  
  181. /* ARGSUSED */
  182. void button(int button, int state, int xpos, int ypos)
  183. {
  184.     if (state == GLUT_DOWN) {
  185.     mouseOriginX = xpos;
  186.     deltaSinceDraw = 0;
  187.     glutIdleFunc(idle);
  188.     return;
  189.     }
  190.  
  191.     if (!moveCalled) {
  192.     if (button == GLUT_MIDDLE_BUTTON) x = 1.;
  193.     else x = (float)xpos / ((float)w / 2.);
  194.     clamp_x();
  195.     deltaSinceDraw = 100000.;
  196.     } 
  197.     moveCalled = 0;
  198.     if (deltaSinceDraw) draw();
  199.     printf("x = %f\n", x);
  200.     glutIdleFunc(NULL);
  201. }
  202.  
  203. void menu(int val) 
  204. {
  205.     operation = val;
  206.     set_img_pointers();
  207.     draw();
  208. }
  209.  
  210. void idle(void)
  211. {
  212.     if (deltaSinceDraw) {
  213.     x += deltaSinceDraw;
  214.     clamp_x();
  215.     draw();
  216.     deltaSinceDraw = 0;
  217.     }
  218. }
  219.  
  220. /* ARGSUSED */
  221. void motion(int xpos, int ypos)
  222. {
  223.     float delta = xpos - mouseOriginX;
  224.     mouseOriginX = xpos;
  225.     moveCalled = 1;
  226.     delta /= w/2.;
  227.     deltaSinceDraw += delta;
  228. }
  229.  
  230. main(int argc, char *argv[])
  231. {
  232.     glutInit(&argc, argv);
  233.     if (argc > 1) {
  234.     load_img(argv[1]);
  235.     } else {
  236.     load_img(defaultFile);
  237.     }
  238.     in0 = black;
  239.     in1 = img;
  240.     operation = BRIGHTNESS;
  241.     glutInitWindowSize(w, h);
  242.     glutInitWindowPosition(0, 0);
  243.     glutInitDisplayMode(GLUT_RGB | GLUT_ACCUM | GLUT_DOUBLE);
  244.     glutCreateWindow(argv[0]);
  245.     glutDisplayFunc(draw);
  246.     glutKeyboardFunc(key);
  247.     glutMotionFunc(motion);
  248.     glutMouseFunc(button);
  249.     glutReshapeFunc(reshape);
  250.  
  251.     glutCreateMenu(menu);
  252.     glutAddMenuEntry("Change brightness", 0);
  253.     glutAddMenuEntry("Change contrast", 1);
  254.     glutAddMenuEntry("Change saturation", 2);
  255.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  256.  
  257.     init();
  258.  
  259.     glutMainLoop();
  260.     return 0;
  261. }
  262.